package com.example.training.service;

import com.example.training.model.entity.Student;
import com.example.training.model.exception.ClientException;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

@Service
public class StudentServiceImpl implements StudentService {

    private final List<Student> studentList = new CopyOnWriteArrayList<>();

    public StudentServiceImpl() {
        initData();
    }
    private void initData() {
        studentList.add(new Student(1, "张三", "男", "北京"));
        studentList.add(new Student(2, "李四", "女", "上海"));
        studentList.add(new Student(3, "王五", "男", "广州"));
        studentList.add(new Student(4, "赵六", "女", "深圳"));
        studentList.add(new Student(5, "钱七", "男", "杭州"));
        studentList.add(new Student(10, "钱七", "男", "杭州"));
        studentList.add(new Student(6, "混五机器学习", "男", "杭州"));
        studentList.add(new Student(7, "六个碎片搜寻", "男", "杭州"));
        studentList.add(new Student(8, "甜八内核加速", "男", "杭州"));
        studentList.add(new Student(9, "钱七认知偏差", "男", "杭州"));
    }

    @Override
    public Map<String, List<Student>> groupStudentsBySex() {
        return studentList.stream()
                .collect(Collectors.groupingBy(Student::getSex));
    }

    @Override
    public Map<String, List<Student>> groupStudentsByFirstLetter() {
        return studentList.stream()
                .collect(Collectors.groupingBy(s -> s.getName().substring(0, 1)));
    }

    //todo It is too complicated here and needs to be re-implemented
    @Override
    public List<String> getDistinctNames() {
        return studentList.stream()
                .map(Student::getName)
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    public Map<Integer, List<Student>> groupStudentsByNameLength() {
        return studentList.stream()
                .collect(Collectors.groupingBy(s -> s.getName().length()));
    }

    @Override
    public List<Student> getSortedStudents(int desc) {
        return studentList.stream()
                .sorted((e1, e2) -> desc == 0 ? 
                       e1.getId() - e2.getId() : 
                       e2.getId() - e1.getId())
                .collect(Collectors.toList());
    }

    @Override
    public String getDistinctHometowns() {
        return studentList.stream()
                .map(Student::getHometown)
                .distinct()
                .collect(Collectors.joining(","));
    }

    @Override
    public boolean addStudent(Student student) {
        if (ObjectUtils.isEmpty(student)){
            throw new ClientException("传入对象不能为空");
        }
        return studentList.add(student);
    }

    @Override
    public List<Student> updateStudents(int id, Student student) {
        if (ObjectUtils.isEmpty(id)){
            throw new ClientException("传入学生ID不能为空");
        }
        if (ObjectUtils.isEmpty(student)){
            throw new ClientException("传入对象不能为空");
        }
        return studentList.stream()
                .map(s -> s.getId().equals(id) ? student : s)
                .map(s -> s.getName().equals(student.getName()) ? student : s)
                .collect(Collectors.toList());
    }

    @Override
    public List<Student> removeStudentsById(int id) {
        if (ObjectUtils.isEmpty(id)) {
            throw new ClientException("传入学生ID不能为空");
        }
        return studentList.stream()
                .filter(s -> s.getId() != id)
                .collect(Collectors.toList());
    }

    @Override
    public List<Student> getAllStudents() {
        return Collections.unmodifiableList(studentList);
    }
}